import os, logging, re, base64, urllib

from google.appengine.api import users
from google.appengine.api import urlfetch
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache

import model
import gmemsess

__author__="elad"
__date__ ="$Mar 1, 2009"

class Alert(webapp.RequestHandler):

	def get(self):
		alerts = self.all_my_alerts()
		template_values = { 'alerts': alerts, }
		path = os.path.join(os.path.dirname(__file__), 'alert.html')
		self.response.out.write(template.render(path, template_values))
	
	def all_my_alerts(self):
		""" retrieve all saved alerts for current user """
		query = model.Alert.all()
		query.filter('user =', users.get_current_user())
		return query.fetch(1000)

class AlertDelete(webapp.RequestHandler):

	def get(self):
		alert = model.Alert.get(self.request.get('key'))
		alert.delete()
		memcache.delete('all_alerts')
		self.redirect("/alerts")

class AlertAdd(webapp.RequestHandler):

	def get(self):
		filter = model.Filter.get(self.request.get('filter'))
		template_values = { 'filter': filter, }
		path = os.path.join(os.path.dirname(__file__), 'new_alert.html')
		self.response.out.write(template.render(path, template_values))

	def post(self):
		""" Add a new alert """
		alert = model.Alert()
		alert.user = users.get_current_user()
		alert.filter = model.Filter.get(self.request.get('filter_key'))
		alert.url = self.request.get('alerturl')
		alert.method = self.request.get('method')
		alert.authentication = self.request.get('auth')
		alert.payload = self.request.get('payload')
		alert.put()
		memcache.delete('all_alerts')
		sess = gmemsess.Session(self)
		sess['alert'] = alert
		self.redirect("/alerts")


class SendAlert:

	@staticmethod
	def send_alert(alert, message):
		if alert.payload:
			form_data = SendAlert.encode_payload(alert, message)
		else:
			form_data = None
		if alert.method == 'POST':
			fetch_method = urlfetch.POST
		else:
			fetch_method = urlfetch.GET
		fetch_headers = {}
		if alert.authentication:
			fetch_headers["Authorization"] = 'Basic ' + base64.b64encode(alert.authentication)
		
		logging.info("Sending to: %s?%s" % (alert.url, form_data))
		
		result = urlfetch.fetch(url=alert.url,
								payload=form_data,
								method=fetch_method,
								headers=fetch_headers)
		
		return result

	VALUE_RE = re.compile('\$((?:message|severity|logger_name|app_name|logger_ip))(?:\[(\d+)\])?')
	
	@staticmethod
	def encode_payload(alert, message):
		lines = alert.payload.splitlines()
		form_fields = {}
		for line in lines:
			if '=' not in line:
				logging.warn("malformatted alert payload line - missing '='")
				continue
			key, value = line.split('=', 1)
			list = SendAlert.VALUE_RE.findall(value)
			for item in list:
				original = '$%s' % item[0]
				if len(item[1]) > 0:
					nchars = int(item[1])
					original += '[%s]' % item[1]
				else:
					nchars = None
				str = message.get_field(item[0], nchars)
				value = value.replace(original, str)
			form_fields[key] = value
		return urllib.urlencode(form_fields)


application = webapp.WSGIApplication([('/alerts/delete', AlertDelete),
									 ('/alerts/add', AlertAdd),
									 ('/alerts', Alert),],
                                    debug=True)

def main():
	logging.getLogger().setLevel(logging.DEBUG)
	run_wsgi_app(application)

if __name__ == "__main__":
	main()

